linux AWS API GATEWAY 支持多个域名精准跨域

葫芦的运维日志

下一篇 搜索 上一篇

浏览量 836

2024/03/28 14:42


AWS API GATEWAY 支持多个域名精准跨域

对于非简单请求添加跨域方法是增加OPTIONS方法,并MOCK 返回

对于这些集成,CORS 协议要求浏览器在发送实际请求之前向服务器发送一个预检请求,并等待来自服务器的批准(或对于凭证的请求)。您必须配置您的 API 以向预检请求发送适当的响应。

要创建预检响应,请执行以下操作:

使用模拟集成创建 OPTIONS 方法。

将以下响应标头添加到 200 方法响应中:

Access-Control-Allow-Headers

Access-Control-Allow-Methods

Access-Control-Allow-Origin

输入响应标头的值。要允许所有来源、所有方法和通用标头,请使用以下标头值:

Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'

Access-Control-Allow-Methods: '*'

Access-Control-Allow-Origin: '*'

创建预检请求后,对于至少所有 200 响应,必须为所有启用 CORS 的方法返回 Access-Control-Allow-Origin: '*' 或 Access-Control-Allow-Origin:'origin' 标头。

综上: aws 只支持通配符和单个精准域名跨域。

多个域名跨时的解决方法

报错

直接在MOCK集成响应添加

method.response.header.Access-Control-Allow-Origin:"https://web.qa.domain.cn, https://app.staging.domain.cn"

请求会发现,报错:

The 'Access-Control-Allow-Origin' header contains multiple values 'https://web.qa.domain.cn, https://app.staging.domain.cn', but only one is allowed.

两种解决方法

  1. 添加在mock方法后添加lambda 模拟返回允许的域名,此种方法会造成费用增加和性能损耗问题。

  2. 在OPTIONS方法中,集中响应内设置 Mapping templates,使用 Velocity Template 语言映射模板来检查允许的域列表并设置原始标头


#set($domains = ["https://web.qa.domain.cn", "https://app.staging.domain.cn"])

#set($origin = $input.params("Origin"))

#if($origin == "")

#set($origin = $input.params("origin"))

#end

#set($origin = $origin.replace(' ', '')))

#if($domains.contains($origin))

#set($context.responseOverride.header.Access-Control-Allow-Origin="$origin")

#set($context.responseOverride.header.Access-Control-Allow-Credentials = 'true')

#set($context.responseOverride.header.Access-Control-Allow-Headers = 'aaa,bbb,ccc,*')
#set($context.responseOverride.header.Access-Control-Allow-Methods = '*')
#set($context.responseOverride.header.Access-Control-Max-Age='1728000')

#end

此时预检查请求option方法时,此方法会根据 header中origin的域名去domains里检查是否存在,如果存在返回对应的 Access-Control-Allow-Origin header。

AWS API GATEWAY to support multiple domain names to accurately cross domains

Adding a cross-domain method for a non-simple request is to add the OPTIONS method and MOCK the return

For these integrations, the CORS protocol requires the browser to send a preflight request to the server and wait for approval (or a request for credentials) from the server before sending the actual request. You must configure your API to send an appropriate response to the preflight request.

To create a preflight response:

Create an OPTIONS method with a mock integration.

Add the following response headers to the 200 method response:

Access-Control-Allow-Headers

Access-Control-Allow-Methods

Access-Control-Allow-Origin

Enter values for the response headers. To allow all origins, all methods, and common headers, use the following header values:

Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'

Access-Control-Allow-Methods: '*'

Access-Control-Allow-Origin: '*'

After creating the preflight request, you must return the Access-Control-Allow-Origin: '*' or Access-Control-Allow-Origin:'origin' header for all CORS-enabled methods for at least all 200 responses.

To sum up: aws only supports wildcards and a single precise domain name cross-domain.

Solution for multiple domains across time

Error reported

Add responses directly in MOCK integration

method.response.header.Access-Control-Allow-Origin:"https://web.qa.domain.cn, https://app.staging.domain.cn"

Request found, error reported:

The 'Access-Control-Allow-Origin' header contains multiple values 'https://web.qa.domain.cn, https://app.staging.domain.cn', but only one is allowed.

Two solutions

  1. Add lambda simulation to return the allowed domain name after the mock method, which will cause cost increase and performance loss.

  2. In the OPTIONS method, set Mapping templates in the centralized response, use the Velocity Template language mapping template to check the list of allowed fields and set the original header.


#set($domains = ["https://web.qa.domain.cn", "https://app.staging.domain.cn"])

#set($origin = $input.params("Origin"))

#if($origin == "")

#set($origin = $input.params("origin"))

#end

#set($origin = $origin.replace(' ', '')))

#if($domains.contains($origin))

#set($context.responseOverride.header.Access-Control-Allow-Origin="$origin")

#set($context.responseOverride.header.Access-Control-Allow-Credentials = 'true')

#set($context.responseOverride.header.Access-Control-Allow-Headers = 'aaa,bbb,ccc,*')
#set($context.responseOverride.header.Access-Control-Allow-Methods = '*')
#set($context.responseOverride.header.Access-Control-Max-Age='1728000')

#end

At this time, when the request option method is pre-checked, this method will go to the domains according to the origin domain name in the header to check whether they exist, and return the corresponding Access-Control-Allow-Origin header if they exist.

葫芦的运维日志

打赏

上一篇 搜索 下一篇
© 冰糖葫芦甜(bthlt.com) 2021 王梓打赏联系方式 陕ICP备17005322号-1